using System;
using System.Threading.Tasks;
using UnityEngine;

namespace RPG.Domain.Character
{
    public class CharacterId : ValueObject
    {
        public Guid Value { get; }

        public CharacterId(Guid value)
        {
            Value = value;
        }

        public static CharacterId Generate()
        {
            return new CharacterId(Guid.NewGuid());
        }
    }

    public class Character : AggregateRoot<CharacterId>
    {
        public string Name { get; private set; }
        public Level Level { get; private set; }
        public Stats Stats { get; private set; }
        public Equipment Equipment { get; private set; }

        private Character() { }

        public static Character Create(string name)
        {
            var character = new Character
            {
                Id = CharacterId.Generate(),
                Name = name,
                Level = new Level(1),
                Stats = Stats.InitialStats(),
                Equipment = new Equipment()
            };

            character.AddDomainEvent(new CharacterCreatedEvent(character.Id, name));
            return character;
        }

        public void LevelUp()
        {
            Level = Level.Increase();
            Stats = Stats.CalculateForLevel(Level);
            AddDomainEvent(new CharacterLevelUpEvent(Id, Level));
        }

        public void EquipItem(Item item)
        {
            if (!item.CanBeEquipped)
                throw new DomainException("This item cannot be equipped.");

            Equipment = Equipment.EquipItem(item);
            Stats = Stats.ApplyEquipmentBonus(Equipment);
            AddDomainEvent(new ItemEquippedEvent(Id, item.Id));
        }
    }
}
